Skip to content

Conversation

@viliakov
Copy link
Contributor

@viliakov viliakov commented Sep 2, 2025

Summary

Extends the stackpack install and stackpack upgrade commands with --wait functionality that monitors operation completion status with configurable timeout.

Changes

Core Functionality

  • Added --wait flag to both stackpack install and stackpack upgrade commands
  • Added --timeout flag with default 1 minute timeout for wait operations
  • Implemented OperationWaiter in cmd/stackpack/common.go for reusable wait logic
  • Status monitoring through existing fetchAllStackPacks() API polling mechanism
  • Proper error handling with detailed API error messages using NewRuntimeError

Architecture

  • Reusable design: OperationWaiter can be used by other commands
  • Clean separation: Common functionality in common.go, command-specific logic in respective files
  • Status constants: StatusInstalled, StatusProvisioning, StatusError for clarity
  • Moved fetchAllStackPacks from stackpack_list.go to common.go for reuse

Behavior

  • Backwards compatible: Wait functionality is optional, existing usage unchanged
  • Configurable polling: 5-second interval with customizable timeout (default 1 minute)
  • Multi-configuration support: Waits for all stackpack configurations to complete
  • Error detection: Returns immediately on configuration errors with detailed messages

Usage Examples

# Install with wait (uses default 1m timeout)
sts stackpack install --name zabbix --wait

# Install with custom timeout
sts stackpack install --name zabbix --wait --timeout 5m

# Upgrade with wait
sts stackpack upgrade --name zabbix --wait --timeout 2m

Testing

Comprehensive Test Coverage

  • 8 new unit tests for OperationWaiter functionality in common_test.go
  • 8 additional integration tests for command-level wait functionality
  • Total 48 tests passing in stackpack package
  • Non-flaky timeout tests with deterministic mocking and stable timing

Test Scenarios Covered

  • ✅ Successful completion detection
  • ✅ Error handling with detailed API error extraction
  • ✅ Timeout scenarios with proper error messages
  • ✅ Multiple configurations handling
  • ✅ StackPack not found scenarios
  • ✅ Flag validation and parsing

Implementation Details

Status Monitoring

  • Polls StackPackConfiguration.Status field through fetchAllStackPacks() API
  • Recognizes INSTALLED (success), PROVISIONING (in progress), ERROR (failure)
  • Extracts detailed error messages from nested API error structures

Error Handling

  • Uses NewRuntimeError to avoid showing usage on operation failures
  • Provides clear, actionable error messages with actual API error details
  • Handles edge cases like stackpack not found, multiple configurations, API failures

Code Quality

  • All tests passing with stable, non-flaky timeout tests
  • Follows existing code patterns and architecture
  • Proper imports and formatting applied
  • Linter compliance (minor warnings about expected code duplication only)

@viliakov
Copy link
Contributor Author

viliakov commented Sep 2, 2025

Manual Testing Report

Test Case 1: Installation fails due to wrong content

Step 1: Scaffold a stackpack project

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack scaffold --name installation-fail

Output:

✓ Validating arguments...
✓ Checking destination directory...
✓ Fetching template from github:StackVista/stackpack-templates@main:templates
✓ Rendering templates...
✓ Validating rendered templates...
✓ Copying files to destination...
Files copied:
  README.md
  provisioning/metricbindings.sty
  provisioning/monitors.sty
  provisioning/remediation-hints/node-memory-pressure.md.hbs
  provisioning/stackpack.sty
  resources/deprovisioning.md
  resources/error.md
  resources/installed.md
  resources/logo.png
  resources/notinstalled.md
  resources/overview.md
  resources/provisioning.md
  resources/waitingfordata.md
  stackpack.conf
✅ ✓ Scaffold complete!

Next steps:
1. Review the generated files in: /Users/viliakov/Workspace/src/github/stackstate-cli/installation-fail
2. Check the /Users/viliakov/Workspace/src/github/stackstate-cli/installation-fail/README.md for instructions on what to do next.

Result: ✅ SUCCESS - Stackpack project scaffolded successfully

Step 2: Make an invalid configuration

Command:

echo "hello world" > installation-fail/provisioning/monitors.sty

Output:

(no output)

Result: ✅ SUCCESS - Invalid content written to monitors.sty

Step 3: Package the stackpack

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d installation-fail

Output:

✅ ✓ Stackpack packaged successfully!

Stackpack: installation-fail (v0.0.1)
Zip file: /Users/viliakov/Workspace/src/github/stackstate-cli/installation-fail-0.0.1.zip

Result: ✅ SUCCESS - Stackpack packaged successfully despite invalid content

Step 4: Upload the stackpack archive

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack upload -f installation-fail-0.0.1.zip

Output:

▀  Awaiting server response..
✅ Uploaded StackPack: installation-fail-0.0.1.zip
NAME              | DISPLAY NAME      | VERSION
installation-fail | installation-fail | 0.0.1

Result: ✅ SUCCESS - Stackpack uploaded successfully

Step 5: Trigger the installation of the stackpack with wait - should fail

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack install --name installation-fail --wait

Output:

▀  Awaiting server response..
Waiting for installation to complete...
❌ Stackpack 'installation-fail' installation failed:
Configuration 110644837847428 failed: while scanning a simple key
 in reader, line 2, column 1:
    hello world
    ^
could not find expected ':'
 in reader, line 4, column 1:
    - _type: MetricBinding
    ^

exit status 9

Result: ✅ SUCCESS - Wait functionality correctly detected installation failure!


Test Case 2: Upgrade fails due to wrong content

Step 1: Scaffold a stackpack project

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack scaffold --name upgrade-fail

Output: ✅ SUCCESS - Scaffolding successful

Steps 2-4: Package, Upload, and Install Initial Version (v0.0.1)

Commands executed successfully:

  • STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d upgrade-fail
  • STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack upload -f upgrade-fail-0.0.1.zip
  • STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack install --name upgrade-fail --wait

Initial Install Output:

Waiting for installation to complete...
✅ StackPack installation completed successfully
ID              | NAME         | STATUS    | VERSION | LAST UPDATED      
262202944126012 | upgrade-fail | INSTALLED | 0.0.1   | Tue Sep 2 21:23:25 2025 CEST

Result: ✅ SUCCESS - Initial installation completed successfully with wait functionality

Steps 5-8: Create Invalid v0.0.2 and Upgrade

Commands:

  • echo "hello world" > upgrade-fail/provisioning/monitors.sty
  • gsed -i 's#version = "0.0.1"#version = "0.0.2"#' upgrade-fail/stackpack.conf
  • STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack package -d upgrade-fail
  • STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack upload -f upgrade-fail-0.0.2.zip

Step 9: Trigger upgrade with wait - should fail

Command:

STS_EXPERIMENTAL_STACKPACK=1 go run main.go stackpack upgrade --name upgrade-fail --unlocked-strategy skip --wait

Output:

▀  Awaiting server response..
Waiting for upgrade to complete...
❌ Stackpack 'upgrade-fail' installation failed:
Configuration 262202944126012 failed: while scanning a simple key
 in reader, line 2, column 1:
    hello world
    ^
could not find expected ':'
 in reader, line 4, column 1:
    - _type: MetricBinding
    ^

exit status 9

Result: ✅ SUCCESS - Wait functionality correctly detected upgrade failure!

deontaljaard
deontaljaard previously approved these changes Sep 3, 2025
@viliakov viliakov merged commit 7d34177 into main Sep 4, 2025
5 checks passed
@viliakov viliakov deleted the STAC-23287 branch September 4, 2025 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants